using UnityEngine;
using UnityEngine.UI;
using Zenject;

namespace Enemy
{
    public class Pointer : MonoBehaviour
    {
        [SerializeField] private Color _pointerColor;
        [SerializeField] private GameObject _pointerIconPrefab;
        [Inject] private Player.Player _player;
        private GameObject _pointerIcon;
        private Transform _canvas;
        private Transform _playerTransform;
        private Camera _mainCamera;

        private void Start()
        {
            if (_player.IsDied)
            {
                enabled = false;
                return;
            }
            Canvas[] canvases = FindObjectsOfType<Canvas>();
            foreach (Canvas canvas in canvases)
            {
                if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)
                {
                    _canvas = canvas.transform;
                    break;
                }
            }
            _mainCamera = Camera.main;
            _pointerIcon = Instantiate(
                _pointerIconPrefab,
                _canvas);
            _pointerIcon.GetComponentInChildren<Image>().color = _pointerColor;
        }

        private void Update()
        {
            Vector3 fromPlayerToSelf = transform.position
                                       - _playerTransform.position;
            Ray ray = new Ray(_playerTransform.position, fromPlayerToSelf);

            Plane[] planes
                = GeometryUtility.CalculateFrustumPlanes(_mainCamera);

            float minDistance = Mathf.Infinity;
            int planeIndex = 0;

            for (int i = 0; i < planes.Length; i++)
            {
                Plane plane = planes[i];
                if (plane.Raycast(ray, out float distance))
                {
                    if (distance < minDistance)
                    {
                        minDistance = distance;
                        planeIndex = i;
                    }
                }
            }

            _pointerIcon.gameObject.SetActive(true);

            Vector3 worldPosition = ray.GetPoint(minDistance);
            _pointerIcon.transform.position = _mainCamera.WorldToScreenPoint(
                worldPosition
            );
            _pointerIcon.transform.rotation = GetIconRotation(planeIndex);
        }

        private static Quaternion GetIconRotation(int planeIndex)
        {
            return planeIndex switch
            {
                0 => Quaternion.Euler(0, 0, 90),
                1 => Quaternion.Euler(0, 0, -90),
                2 => Quaternion.Euler(0, 0, 180),
                3 => Quaternion.Euler(0, 0, 0),
                _ => Quaternion.identity
            };
        }

        public void Destroy()
        {
            Destroy(_pointerIcon);
            enabled = false;
        }
    }
}
